I took a riffle-ito with a thermister and photocell out in my kayak. I stopped at three locations in the middle of the riffle, and slowly lowered the riffle to the bottom, and then slowly pulled it back up. THe goal was to see if I could measure a change in light levels, and whether the temperature decreased with depth indicating stratification. I also had an Arduino Uno with a GPS Shield logging my location.
library(dplyr)
library(tidyr)
library(lubridate)
library(ggplot2)
library(ggmap)
theme_set(theme_bw())
gps <- read.csv('./data/GPSLOG10.CSV', header=FALSE, as.is=TRUE)
names(gps) <- c('DATETIME_UTC','FIX','FIX_QUALITY','LATITUDE','LONGITUDE','SPEED','ANGLE','ALTITUDE','NUM_SATELLITES')
gps <- mutate(gps, DATETIME=ymd_hms(DATETIME_UTC, tz="UTC") %>% with_tz(tzone="US/Eastern"),
LATITUDE=floor(LATITUDE/100) + (LATITUDE %% 100)/60,
LONGITUDE=floor(LONGITUDE/100) + (LONGITUDE %% 100)/60,
LONGITUDE=-LONGITUDE) %>%
filter(LATITUDE > 0)
Here are the locations recorded by the GPS, which show the path of the kayak. I didn’t turn on the GPS until I got in the kayak, and it apparently took a few minutes for it to fix a signal. Next time, I should turn on the GPS a few minutes before I leave.
map <- get_map(location=c(lon=mean(range(gps$LONGITUDE)), lat=mean(range(gps$LATITUDE))),
zoom=17, maptype="satellite")
## Map from URL : http://maps.googleapis.com/maps/api/staticmap?center=43.922395,-69.960757&zoom=17&size=%20640x640&scale=%202&maptype=satellite&sensor=false
## Google Maps API Terms of Service : http://developers.google.com/maps/terms
ggmap(map, darken=c(0.25, "white"), extent="device") +
geom_point(aes(LONGITUDE, LATITUDE), data=gps, color='red', size=1)
Load the riffle-ito data from a csv file. Note that the PHOTO values are inversely proportional to the light levels (higher PHOTO values -> lower light levels). So I’ll reverse the PHOTO values by subtracting them from the maximum analog reading of 1023 (as was done by Adafruit).
wq <- read.csv('data/LOGGER36.CSV', as.is=TRUE)
wq <- mutate(wq, DATETIME=ymd_hms(DATETIME, tz="US/Eastern")) %>%
filter(DATETIME <= max(gps$DATETIME)) # %>%
# mutate(PHOTO=1023-PHOTO) # reverse
head(wq)
## DATETIME RTC_TEMP_C TEMP_C PHOTO BATTERY_LEVEL
## 1 2014-08-08 18:13:10 26 26.63 428 706
## 2 2014-08-08 18:13:15 0 26.63 382 706
## 3 2014-08-08 18:13:21 26 26.63 511 706
## 4 2014-08-08 18:13:26 27 26.63 350 706
## 5 2014-08-08 18:13:31 27 26.63 519 706
## 6 2014-08-08 18:13:37 27 26.63 398 706
Here is a timeseries of the riffle-ito temperature.
ggplot(wq, aes(DATETIME, TEMP_C)) +
geom_line() +
labs(x="Time", y="Temp (degC)")
Note the high temperature at the beginning reflects the hot air temperature in my house. I’ll truncate the data to begin at 18:22 when the riffle was outside.
wq <- filter(wq, DATETIME >= ymd_hms("2014-08-08 18:22:00", tz="US/Eastern"))
Now plot the raw data again.
ggplot(wq, aes(DATETIME, TEMP_C)) +
geom_line() +
labs(x="Time", y="Temp (degC)")
Here is a timeseries of the riffle-ito photoresistor. The high values indicate high light levels.
ggplot(wq, aes(DATETIME, PHOTO)) +
geom_line() +
labs(x="Time", y="Photo")
To determine if the bottom water had lower temperature than the air, we can make a scatter plot. Surprisingly, we see the opposite trend with the highest temperatures corresponding to the lowest light levels.
ggplot(wq, aes(TEMP_C, PHOTO)) +
geom_point() +
labs(x="Temp (degC)", y="Photo")
To merge the GPS and Riffle-ito data, I’ll linearly interpolate the longitude, latitude, and speed as recorded by the GPS to match the time points measured by the riffle. Then I’ll join the two tables by the 1-minute rounded DATETIME.
gps.interp <- data.frame(DATETIME=wq$DATETIME,
LONGITUDE=approx(x=gps$DATETIME, y=gps$LONGITUDE,
xout=wq$DATETIME)$y,
LATITUDE=approx(x=gps$DATETIME, y=gps$LATITUDE,
xout=wq$DATETIME)$y,
SPEED=approx(x=gps$DATETIME, y=gps$SPEED,
xout=wq$DATETIME)$y
)
df <- merge(wq, gps.interp, by="DATETIME", all.x=TRUE)
This map shows the track with points colored by temperature. I’m also truncating the end of the trip to remove data when I was paddling home (as the riffle was out of the water and in the canoe). Note the two locations with the highest temperature.
df <- filter(df, DATETIME<=ymd_hms("2014-08-08 18:36:00", tz="US/Eastern"))
ggmap(map, darken=c(0.25, "white"), extent="device") +
geom_point(aes(LONGITUDE, LATITUDE, color=TEMP_C), data=df, size=2) +
scale_color_gradient(low='green', high='red')
## Warning: Removed 11 rows containing missing values (geom_point).
And this is a map of the light levels.
ggmap(map, darken=c(0.25, "white"), extent="device") +
geom_point(aes(LONGITUDE, LATITUDE, color=PHOTO), data=df, size=2) +
scale_color_gradient(low='green', high='red')
## Warning: Removed 11 rows containing missing values (geom_point).
To try and identify which riffle measurements were collected when the riffle was in the water, I can try plotting my speed vs the photo level.
ggplot(df, aes(SPEED, PHOTO)) +
geom_point()
## Warning: Removed 11 rows containing missing values (geom_point).
This figure plots light levels, temperature and speed on identical x-axes for comparison. The time with high speed was when I paddled from the second drop to the third drop location.
filter(df, DATETIME > ymd_hm("2014-08-08 18:25", tz="US/Eastern")) %>%
select(DATETIME, TEMP_C, PHOTO, SPEED) %>%
gather(VAR, VALUE, TEMP_C, PHOTO, SPEED) %>%
ggplot(aes(DATETIME, VALUE)) +
geom_line() +
facet_wrap(~VAR, scales='free_y', ncol=1)
Here is the light level over time colored by temperature for the first drop. I’m not completely sure if this is set to the proper beginning. It may have begin around 18:24:30 because the higher temperatures at the beginning of the drop suggest the riffle-ito may have been responding to the air temperature, and that it didn’t start measuring the water temperature until around 18:24:30.
filter(df,
DATETIME >= ymd_hms("2014-08-08 18:23:00", tz="US/Eastern"),
DATETIME <= ymd_hms("2014-08-08 18:26:10", tz="US/Eastern")) %>%
ggplot(aes(DATETIME, PHOTO, color=TEMP_C)) +
geom_point(size=3) +
geom_line() +
scale_color_gradient(low='green', high='red')
This figure shows the same data and indicates higher temperatures at higher light levels. Although based on the previous figure, we know these are from the beginning of the drop when the riffle may have simply been adjusting to the air temperature, or been slowly responding to the change from air to water.
filter(df,
DATETIME >= ymd_hms("2014-08-08 18:23:00", tz="US/Eastern"),
DATETIME <= ymd_hms("2014-08-08 18:26:10", tz="US/Eastern")) %>%
ggplot(aes(PHOTO, TEMP_C, color=TEMP_C)) +
geom_point(size=3) +
scale_color_gradient(low='green', high='red')
And here is a map of the first drop location. The green areas show where the riffle was close to the bottom with the lowest light.
ggmap(map, darken=c(0.25, "white"), extent="device") +
geom_point(aes(LONGITUDE, LATITUDE, color=PHOTO),
data=filter(df, DATETIME >= ymd_hms("2014-08-08 18:23:00", tz="US/Eastern"),
DATETIME <= ymd_hms("2014-08-08 18:26:10", tz="US/Eastern")),
size=2) +
scale_color_gradient(low='green', high='red')
And here’s the same map colored by temperature. Clearly the temperature was higher at the beginning than the end. If this experiment worked correctly then I’d expect the same kind of pattern with the lowest temperature corresponding to the lowest light levels.
ggmap(map, darken=c(0.25, "white"), extent="device") +
geom_point(aes(LONGITUDE, LATITUDE, color=TEMP_C),
data=filter(df, DATETIME >= ymd_hms("2014-08-08 18:23:00", tz="US/Eastern"),
DATETIME <= ymd_hms("2014-08-08 18:26:10", tz="US/Eastern")),
size=2) +
scale_color_gradient(low='green', high='red')
Here is the light level over time colored by temperature for the second drop. Again, I would expect to see the lowest temperatures corresponding to the lowest light levels.
filter(df,
DATETIME >= ymd_hms("2014-08-08 18:26:35", tz="US/Eastern"),
DATETIME <= ymd_hms("2014-08-08 18:30:20", tz="US/Eastern")) %>%
ggplot(aes(DATETIME, PHOTO, color=TEMP_C)) +
geom_point(size=3) +
geom_line() +
scale_color_gradient(low='green', high='red')
And here is a map of the second drop location.
ggmap(map, darken=c(0.25, "white"), extent="device") +
geom_point(aes(LONGITUDE, LATITUDE, color=PHOTO),
data=filter(df, DATETIME >= ymd_hms("2014-08-08 18:26:35", tz="US/Eastern"),
DATETIME <= ymd_hms("2014-08-08 18:30:20", tz="US/Eastern")),
size=2) +
scale_color_gradient(low='green', high='red')
And here’s the same map colored by temperature. Again the temperature was higher at the beginning than the end.
ggmap(map, darken=c(0.25, "white"), extent="device") +
geom_point(aes(LONGITUDE, LATITUDE, color=TEMP_C),
data=filter(df, DATETIME >= ymd_hms("2014-08-08 18:26:35", tz="US/Eastern"),
DATETIME <= ymd_hms("2014-08-08 18:30:20", tz="US/Eastern")),
size=2) +
scale_color_gradient(low='green', high='red')
Finally, light levels for the final drop. Same pattern as before.
filter(df,
DATETIME >= ymd_hms("2014-08-08 18:32:05", tz="US/Eastern"),
DATETIME <= ymd_hms("2014-08-08 18:35:30", tz="US/Eastern")) %>%
ggplot(aes(DATETIME, PHOTO, color=TEMP_C)) +
geom_point(size=3) +
geom_line() +
scale_color_gradient(low='green', high='red')
And the map of light levels
ggmap(map, darken=c(0.25, "white"), extent="device") +
geom_point(aes(LONGITUDE, LATITUDE, color=PHOTO),
data=filter(df, DATETIME >= ymd_hms("2014-08-08 18:32:05", tz="US/Eastern"),
DATETIME <= ymd_hms("2014-08-08 18:35:30", tz="US/Eastern")),
size=2) +
scale_color_gradient(low='green', high='red')
And the map of temperature.
ggmap(map, darken=c(0.25, "white"), extent="device") +
geom_point(aes(LONGITUDE, LATITUDE, color=TEMP_C),
data=filter(df, DATETIME >= ymd_hms("2014-08-08 18:32:05", tz="US/Eastern"),
DATETIME <= ymd_hms("2014-08-08 18:35:30", tz="US/Eastern")),
size=2) +
scale_color_gradient(low='green', high='red')